﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNet.SignalR;
using DeviceModel;

namespace DashboardApp.DataProviders
{
    public class DeviceDataProvider
    {
        private List<CategoryInfo> categoriesInfo = new List<CategoryInfo>();
        private List<DeviceInfo> devicesInfo = new List<DeviceInfo>();
        private List<Device> devices = new List<Device>();
        
        private DeviceDataProvider()
        {
        }

        private static DeviceDataProvider ob;
        private string uriPrefix;

        public static DeviceDataProvider Instance
        {
            get
            {
                if (ob == null)
                    ob = new DeviceDataProvider();

                return ob;
            }
        }

        public List<Device> Devices
        {
            get
            {
                lock (this)
                    return devices;
            }
        }

        public int[] AddCategoriesInfo(params CategoryInfo[] categoriesInfo) 
        {
            var ids = new List<int>();
            lock (this) 
            {
                if (categoriesInfo != null && categoriesInfo.Length > 0)
                    foreach (var category in categoriesInfo)
                    {
                        bool isNew;
                        if (isNew = category.IsNew(this.categoriesInfo))
                        {
                            ids.Add(category.Id);
                            this.categoriesInfo.Add(category);
                        }
                    }
            }

            return ids.ToArray();
        }

        public int[] AddDevicesInfo(params DeviceInfo[] dis)
        {
            var ids = new List<int>();
            lock (this)
            {
                if (dis != null && dis.Length > 0)
                    foreach (var di in dis)
                        if (di.IsNew(devicesInfo))
                        {
                            var category = categoriesInfo.Where(c => c.DoesBelongTo(di.Id)).FirstOrDefault();
                            if (category != null)
                                di.CategoryId = category.Id;

                            ids.Add(di.Id);
                            devicesInfo.Add(di);

                            devices.Add(new Device { Id = di.Id, Status = DeviceStatus.NoData });
                        }
            }

            return ids.ToArray();
        }

        public DeviceStatus this[int deviceId]
        {
            set 
            {
                lock (this)
                {
                    var device = devices.Where(d => d.Id == deviceId).FirstOrDefault();
                    if (device != null)
                        device.Status = value;
                }
            }
        }

        public string UriKeepAlive
        {
            get
            {
                lock (this)
                    return uriPrefix;
            }
            set
            {
                lock (this)
                    uriPrefix = value;
            }
        }

        public void Update<T>(T hub = null) where T : Hub
        {
            lock (this)
                if (devices.Count > 0)
                    (hub == null ? GlobalHost.ConnectionManager.GetHubContext<T>().Clients.All : hub.Clients.All).All(new List<object> 
                                        {
                                            categoriesInfo,
                                            devicesInfo,
                                            devices
                                        })                   
                        .Wait();
        }
    }
}